#include "PThread.hpp"
#include <vector>
#include <mutex>

// 局部锁 ---- V2
using namespace Threadnode;

#define NUM 4
int ticketnum = 100000;
int cut = 0;
std::mutex gmtx;

class TicketData
{
public:
	std::string name;
	pthread_mutex_t *lo_ck;
};

void Ticket(TicketData& td)
{
	while(true)
	{
		// pthread_mutex_lock(td.lo_ck);
		gmtx.lock();

		if(ticketnum > 0)
		{
			// usleep(1000);
			printf("get a new ticket,id: %d, cut: %d, name: %s\n",ticketnum--,cut++,td.name.c_str());

			gmtx.unlock();
			// pthread_mutex_unlock(td.lo_ck);
		}
		else
		{
			gmtx.unlock();
			// pthread_mutex_unlock(td.lo_ck);
			break;
		}
	}
}

int main()
{
	pthread_mutex_t lock;
	pthread_mutex_init(&lock,nullptr);
	std::vector<thread<TicketData>> threads;

	for(int i = 0 ; i < NUM;i++)
	{
		TicketData *td = new TicketData();
		td->lo_ck = &lock;
		
		threads.emplace_back(Ticket,*td);
		threads.back().data().name = threads.back().name();
	}

	for(int i = 0;i < NUM;i++)
	{
		threads[i].start();
	}
	for(int i = 0;i < NUM;i++)
	{
		threads[i].join();
	}
	pthread_mutex_destroy(&lock);
	return 0;
}


// 全局锁-----V1
// using namespace Threadnode;

// #define NUM 4
// int ticketnum = 100000;

// pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

// int cut = 0;

// void Ticket()
// {
// 	while(true)
// 	{
// 		pthread_mutex_lock(&lock);
// 		if(ticketnum > 0)
// 		{
// 			usleep(1000);
// 			printf("get a new ticket,id: %d %d\n",ticketnum--,cut++);
// 			pthread_mutex_unlock(&lock);
// 		}
// 		else
// 		{
// 			pthread_mutex_unlock(&lock);
// 			break;
// 		}
// 	}
// }

// int main()
// {
// 	std::vector<thread> threads;

// 	for(int i = 0 ; i < NUM;i++)
// 	{
// 		threads.emplace_back(Ticket);
// 	}

// 	for(int i = 0;i < NUM;i++)
// 	{
// 		threads[i].start();
// 	}
// 	for(int i = 0;i < NUM;i++)
// 	{
// 		threads[i].join();
// 	}
// 	return 0;
// }
